import random
import string
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import io
import os


# 生成随机验证码字符串
def generate_captcha_text(length=4):
    # 移除容易混淆的字符如l、1、i、0、o
    characters = string.ascii_uppercase + string.digits.replace('0', '').replace('1', '').replace('I', '').replace('O',
                                                                                                                   '')
    return ''.join(random.choice(characters) for _ in range(length))


# 创建验证码图片
def create_captcha_image(text):
    # 设置图片尺寸
    width, height = 120, 40

    # 创建图像
    image = Image.new('RGB', (width, height), color=(240, 240, 240))
    draw = ImageDraw.Draw(image)

    # 获取当前文件所在目录
    base_dir = os.path.dirname(os.path.abspath(__file__))
    # 加载字体文件
    font_path = os.path.join(base_dir, 'fonts', 'Arial.ttf')

    try:
        # 尝试加载指定字体
        font = ImageFont.truetype(font_path, 28)
    except IOError:
        # 如果字体文件不存在，使用默认字体
        font = ImageFont.load_default()

    # 绘制字符
    for i, char in enumerate(text):
        x = 10 + i * 25 + random.randint(-5, 5)
        y = 5 + random.randint(-5, 5)
        color = (random.randint(30, 120), random.randint(30, 120), random.randint(30, 120))
        draw.text((x, y), char, font=font, fill=color)

    # 添加干扰线
    for _ in range(random.randint(2, 4)):
        x1 = random.randint(0, width // 2)
        y1 = random.randint(0, height)
        x2 = random.randint(width // 2, width)
        y2 = random.randint(0, height)
        line_color = (random.randint(100, 200), random.randint(100, 200), random.randint(100, 200))
        draw.line([(x1, y1), (x2, y2)], fill=line_color, width=1)

    # 添加噪点
    for _ in range(random.randint(100, 200)):
        x = random.randint(0, width - 1)
        y = random.randint(0, height - 1)
        pixel_color = (random.randint(150, 255), random.randint(150, 255), random.randint(150, 255))
        image.putpixel((x, y), pixel_color)

    # 应用滤镜
    image = image.filter(ImageFilter.SMOOTH)

    # 保存图像到内存
    buffer = io.BytesIO()
    image.save(buffer, format='PNG')
    buffer.seek(0)

    return buffer